from vtk import *
class Drawer:
    def __init__(self, extent,maxlev,vertex,vertex_inv, target_view,g,txt):
        self.g = g
        self.maxlev = maxlev
        self.extent = extent
        self.vertex = vertex
        self.vertex_inv = vertex_inv
        self.view2 = target_view
        self.txt = txt
        
    def printParents(self,e):
        if self.extent[e]["level"] <= 0:
            return []
        result = []
        for p in self.extent[e]["parents"]:
            #arrow = str(extent[e]["level"])
            #for i in range(extent[e]["level"]-1):
            #	arrow += "-"
            #print arrow+">"+str(extent[p]["objects"][:5])
            result.append(p)
            parents = self.printParents(p)
            for i in parents:
                if i not in result:
                    result.append(i)
        return result
	
    def printChildren(self,e):
        if self.extent[e]["level"] >= self.maxlev:
            return []
        result = []
        for p in self.extent[e]["children"]:
            #arrow = str(extent[e]["level"])
            #for i in range(extent[e]["level"]-1):
            #	arrow += "-"
            #print arrow+">"+str(extent[p]["objects"][:5])
            result.append(p)
            children = self.printChildren(p)
            for i in children:
                if i not in result:
                    result.append(i)
        return result
    
    def updateText(self,x):
        concept = self.extent[self.vertex_inv[int(x)]]
        summary = 'Concept ID: {} \n'.format(x)
        summary += 'Level: {} \n'.format(concept['level'])
        summary += 'Extent: {} \n'.format(concept['objects'])
        summary += 'Intent: {} \n'.format(concept['attributes'])        
        summary += 'Stability: {} \n'.format(concept['stability'])        
        #summary += str(concept)
        self.txt.SetInput(summary)
    
    def selectionCallback2(self,caller, event):
        fil = vtkIdTypeArray()
        print "Searching subgraph..."
        
        sel = caller.GetCurrentSelection()
        node0 = sel.GetNode(1)
        
        if node0.GetFieldType() == 3:
            sl = node0.GetSelectionList()
            if sl.GetNumberOfTuples() < 1:
                print "No concept selected"
                return
        else:
            print "No node selected"
            return
        
        for i in range(node0.GetSelectionList().GetNumberOfTuples()):
            print node0.GetSelectionList().GetValue(i)
        x = node0.GetSelectionList().GetValue(0)

        bfs = vtkBoostBreadthFirstSearch()
        bfs.AddInputConnection(self.g.GetProducerPort())
        bfs.SetOriginVertex(x)
        
        cutter = vtkSelectionSource()
        cutter.SetContentType(7)               
        cutter.SetFieldType(3)                 
        cutter.SetArrayName("BFS")
        cutter.AddThreshold(0,100)          
        cutter.Update()
                
        extract_graph = vtkExtractSelectedGraph()
        extract_graph.AddInputConnection(bfs.GetOutputPort())
        extract_graph.SetSelectionConnection(cutter.GetOutputPort())
        extract_graph.Update()
        
        
        #sel = cutter.GetOutput()
        node0.SetSelectionList(cutter.GetOutput().GetNode(0).GetSelectionList())

        self.updateText(x)
        sel.Update()
        
        self.view2.AddRepresentationFromInputConnection(extract_graph.GetOutputPort())
        self.view2.SetLayoutStrategyToPassThrough()
        self.view2.ResetCamera()
        self.view2.Render()
        print "Subgraph search ended"
		
	def selectionCallback(self,caller, event):
		fil = vtkIdTypeArray()
		print "Searching subgraph..."

		sel = caller.GetCurrentSelection()
		print sel
		node0 = sel.GetNode(1)
		
		if node0.GetFieldType() == 3:
			sl = node0.GetSelectionList()
			if sl.GetNumberOfTuples() > 0:
				fil.InsertValue(0,sl.GetValue(0))
				parents = self.printChildren(self.vertex_inv[sl.GetValue(0)])
				j = 1
				for p in parents:
					fil.InsertValue(j, int(self.vertex[p]))
					j += 1
			
			else:
				print "No concept selected"
		node0.SetSelectionList(fil)
		node0.SetContentType(vtkSelectionNode.INDICES);
		node0.SetFieldType(vtkSelectionNode.VERTEX);
		
		sel.Update()
		
		extract_graph = vtkExtractSelectedGraph()
		extract_graph.SetInput(0,self.g)
		extract_graph.SetInput(1,sel)
		extract_graph.Update()
		print "EDGES: ",extract_graph.GetOutput().GetNumberOfEdges()
		
		self.view2.AddRepresentationFromInputConnection(extract_graph.GetOutputPort())
		self.view2.SetLayoutStrategyToPassThrough()
		self.view2.ResetCamera()
		self.view2.Render()
		print "Subgraph search ended"
	 
	def printFieldType(self,field_type):
	       if field_type == 3:
		       print "Vertices Selected:"
	       elif field_type == 4:
		       print "Edges Selected:"
	       else:
		       print "Unknown type:"

##################################################################
# FUNCTIONS REQUIRED FOR MAC COMPATIBILITY
# press p to toggle panning
# press z to toggle zooming
# press s to toggle select
##################################################################
def keyPress(obj,event):
    int = obj.GetInteractor()
    key = int.GetKeySym()
    if key == 'p':
        obj.RemoveObservers("LeftButtonPressEvent")
        obj.RemoveObservers("LeftButtonReleaseEvent")
        obj.AddObserver("LeftButtonPressEvent",startPan)
        obj.AddObserver("LeftButtonReleaseEvent",endPan)
    if key == 'z':
        obj.RemoveObservers("LeftButtonPressEvent")
        obj.RemoveObservers("LeftButtonReleaseEvent")
        obj.AddObserver("LeftButtonPressEvent",startZoom)
        obj.AddObserver("LeftButtonReleaseEvent",endZoom)
    if key == 's':
        obj.RemoveObservers("LeftButtonPressEvent")
        obj.RemoveObservers("LeftButtonReleaseEvent")
        obj.AddObserver("LeftButtonPressEvent",startSelect)
        obj.AddObserver("LeftButtonReleaseEvent",endSelect)
    obj.OnChar()

def startPan(obj,event):
    print 'panning'
    obj.OnMiddleButtonDown()
def endPan(obj,event):
    obj.OnMiddleButtonUp()

def startZoom(obj,event):
    print 'zooming'
    obj.OnRightButtonDown()
def endZoom(obj,event):
    obj.OnRightButtonUp()

def startSelect(obj,event):
    print 'selecting'
    obj.OnLeftButtonDown()
def endSelect(obj,event):
    obj.OnLeftButtonUp()


